using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace UtilZ.Dotnet.Ex.Base
{
#pragma warning disable 8500 // address / sizeof of managed types

    /// <summary>
    /// 非托管内存指针辅助类
    /// </summary>
    unsafe public static class UnmanagedMemoryHelper
    {
        /// <summary>
        /// 获取Span数据指向的起始指针
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="span">Span数据</param>
        /// <returns>Span数据指向的起始指针</returns>
        public static T* GetSpanPointer<T>(this Span<T> span)
            where T : struct
        {
#if NET4_0
            return span.DataPtr;
#else
            return (T*)Unsafe.AsPointer<T>(ref span[0]);
#endif
        }

        /// <summary>
        /// 用指定的值填充到当前对象数据指针指向的内容
        /// </summary>
        /// <param name="ptr">要填充的指针地址</param>
        /// <param name="elementCount">填充元素个数</param>
        /// <param name="value">填充值</param>
        public static void Fill<T>(void* ptr, long elementCount, T value) where T : struct
        {
            if (elementCount <= 0)
            {
                return;
            }

            if (sizeof(T) == 1)
            {
                NativeMemory.Fill(ptr, (nuint)elementCount, *((byte*)&value));
            }
            else
            {
                var ptr2 = (T*)ptr;
                for (uint i = 0; i < elementCount; i++)
                {
                    ptr2[i] = value;
                }
            }
        }


#if !NET4_0
        /// <summary>
        /// 升序排序
        /// </summary>
        /// <exception cref="InvalidOperationException">未实现比较接口时类型不支持排序异常</exception>
        public static void Sort<T>(this Span<T> data)
        {
            T temp = default(T);
            if (temp is IComparable<T>)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    for (int j = i + 1; j < data.Length; j++)
                    {
                        if (((IComparable<T>)data[j]).CompareTo(data[i]) < 0)
                        {
                            temp = data[i];
                            data[i] = data[j];
                            data[j] = temp;
                        }
                    }
                }
            }
            else if (temp is IComparable)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    for (int j = i + 1; j < data.Length; j++)
                    {
                        if (((IComparable)data[j]).CompareTo(data[i]) < 0)
                        {
                            temp = data[i];
                            data[i] = data[j];
                            data[j] = temp;
                        }
                    }
                }
            }
            else
            {
                throw new InvalidOperationException($"类型\"{typeof(T).FullName}\"未实现\"{nameof(IComparable)}\"接口或\"{nameof(IComparable<T>)}\"接口,不支持排序.");
            }
        }
#endif



    }



}
